﻿using MODEL;
using SysCommon;
using SysHelper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SysController
{
    public static class CurrencyRateController
    {
        #region 1.0 获取币种 +static List<Currency> GetCurrency(int CurrencyId = -1, bool IsDel = false)
        /// <summary>
        /// 获取币种
        /// </summary>
        /// <param name="CurrencyId">币种ID</param>
        /// <param name="IsDel">启用</param>
        /// <returns>币种信息</returns>
        public static List<Currency> GetCurrency(int CurrencyId = -1, bool IsDel = false)
        {
            List<Currency> list = null;
            if (CurrencyId == -1)
            {
                list = OperateContext.CurrentContext.BllSession.ICurrency_BLL.GetListByWhere(s => s.IsDel == IsDel).ToList();
            }
            else
            {
                list = OperateContext.CurrentContext.BllSession.ICurrency_BLL.GetListByWhere(s => s.IsDel == IsDel && s.CurrencyID == CurrencyId).ToList();
            }
            return list;
        }
        #endregion

        #region 1.1 获取汇率 + static List<RateOfExchange> GetRateOfExchange(int CurrencyId = -1, bool RateType = false, bool IsDel = false)
        /// <summary>
        /// 获取汇率
        /// </summary>
        /// <param name="CurrencyId">币种ID</param>
        /// <param name="RateType">汇率类型：0 为结算汇率，1为定价汇率</param>
        /// <param name="IsDel">启用</param>
        /// <returns>系统汇率信息</returns>
        public static List<RateOfExchange> GetRateOfExchange(int CurrencyId = -1, bool RateType = false, bool IsDel = false)
        {
            List<RateOfExchange> list = null;
            if (CurrencyId == -1)
            {
                list = OperateContext.CurrentContext.BllSession.IRateOfExchange_BLL.GetListByWhere(s => s.RateType == RateType && s.IsDel == IsDel).ToList();
            }
            else
            {
                list = OperateContext.CurrentContext.BllSession.IRateOfExchange_BLL.GetListByWhere(s => s.CurrencyID == CurrencyId && s.RateType == RateType && s.IsDel == IsDel).ToList();
            }
            return list;
        }
        #endregion

        #region 1.2 获取实时汇率
        /// <summary>
        /// 获取实时汇率（CurrencyID)
        /// </summary>
        /// <returns>币种ID，实时汇率</returns>
        public static Dictionary<int, decimal> GetRate()
        {
            Dictionary<int, decimal> dict = new Dictionary<int, decimal>();
            var list = GetCurrency().Select(s => new { s.CurrencyID, s.CurrencyName }).ToList();
            foreach (var item in list)
            {
                if (item.CurrencyID == 0) continue;
                decimal rate = CurrencyRate.GetExchangeRate(item.CurrencyName);
                dict.Add(item.CurrencyID, rate);
            }
            return dict;
        }

        /// <summary>
        /// 获取实时汇率(List Currency)
        /// </summary>
        /// <param name="Currencylist"></param>
        /// <returns></returns>
        public static Dictionary<int, decimal> GetRate(List<Currency> Currencylist)
        {
            Dictionary<int, decimal> dict = new Dictionary<int, decimal>();
            var list = Currencylist.Select(s => new { s.CurrencyID, s.CurrencyName }).ToList();
            foreach (var item in list)
            {
                if (item.CurrencyID == 0) continue;
                decimal rate = CurrencyRate.GetExchangeRate(item.CurrencyName);
                dict.Add(item.CurrencyID, rate);
            }
            return dict;
        }

        /// <summary>
        /// 获取实时汇率（CurrencyName)
        /// </summary>
        /// <returns>币种名称，获取实时汇率</returns>
        public static Dictionary<string, decimal> GetRate(string BackName)
        {
            Dictionary<string, decimal> dict = new Dictionary<string, decimal>();
            var list = GetCurrency().Select(s => new { s.CurrencyID, s.CurrencyName }).ToList();
            foreach (var item in list)
            {
                if (item.CurrencyID == 0) continue;
                decimal rate = CurrencyRate.GetExchangeRate(item.CurrencyName);
                dict.Add(item.CurrencyName, rate);
            }
            return dict;
        }
        /// <summary>
        ///  单个获取实时汇率（CurrencyName)
        /// </summary>
        /// <param name="CurrencyName">币种名称</param>
        /// <param name="ToCurrencyName">目标币种名称</param>
        /// <returns>汇率</returns>
        public static decimal GetRate(string CurrencyName, string ToCurrencyName = null)
        {
            decimal rate = 0.0000m;
            if (string.IsNullOrEmpty(ToCurrencyName))
            {
                rate = CurrencyRate.GetExchangeRate(CurrencyName);
            }
            else
            {
                rate = CurrencyRate.GetExchangeRate(CurrencyName, ToCurrencyName);
            }
            return rate;
        }
        #endregion

        #region 1.3 实时备份汇率 +static int BackRateOfExchange()
        /// <summary>
        /// 实时备份汇率
        /// </summary>
        /// <returns>备份成功数</returns>
        public static int BackRateOfExchange()
        {
            Dictionary<int, decimal> list = GetRate();
            foreach (var item in list)
            {
                OperateContext.CurrentContext.BllSession.IRateOfExchangeHistory_BLL.ADD(new RateOfExchangeHistory()
                {
                    CurrencyID = item.Key,
                    CreateTime = DateTime.Now,
                    CreateUser = "Back",
                    UpdateUser = "RealRate",
                    UpdateTime = DateTime.Now,
                    Rate = item.Value,
                    RateType = false,
                    IsDel = false
                });
            }
            return OperateContext.CurrentContext.BllSession.SaveChanges(typeof(RateOfExchangeHistory).Name);
        }
        #endregion

        #region 1.4 实时汇率更新汇率 +static int UpdateRate(bool RateType = false)
        /// <summary>
        /// 实时汇率更新汇率
        /// </summary>
        /// <param name="RateType">汇率类型（结算0，定价1）</param>
        /// <returns>更新成功数</returns>
        public static int UpdateRate(bool RateType = false)
        {
            Dictionary<int, decimal> dict = GetRate();
            if (dict.Count < 1) return -1;
            foreach (var item in dict)
            {
                RateOfExchange rate = new RateOfExchange()
                {
                    Rate = item.Value,
                    CurrencyID = item.Key,
                    RateType = RateType,
                    IsDel = false,
                    CreateUser = "UpdateRate",
                    CreateTime = DateTime.Now,
                    UpdateUser = "UpdateRate",
                    UpdateTime = DateTime.Now
                };
                OperateContext.CurrentContext.BllSession.IRateOfExchange_BLL.ModifyIsNullADD(rate, s => s.CurrencyID == item.Key && s.RateType == RateType && s.IsDel == false, false, "Rate", "UpdateUser", "UpdateTime");
            }
            return OperateContext.CurrentContext.BllSession.SaveChanges(typeof(RateOfExchange).Name);
        }
        #endregion

        #region 1.5 更新汇率 +static int UpdateRate(Dictionary<int, decimal> dict, bool RateType = true)
        /// <summary>
        ///  更新汇率
        /// </summary>
        /// <param name="dict">新汇率数据字典</param>
        /// <param name="RateType">汇率类型（结算0，定价1）</param>
        /// <returns>更新成功数</returns>
        public static int UpdateRate(Dictionary<int, decimal> dict, bool RateType = true)
        {
            if (dict.Count < 1) return -1;
            foreach (var item in dict)
            {
                RateOfExchange rate = new RateOfExchange()
                {
                    Rate = item.Value,
                    CurrencyID = item.Key,
                    RateType = RateType,
                    IsDel = false,
                    CreateUser = "UpdateRate",
                    CreateTime = DateTime.Now,
                    UpdateUser = "UpdateRate",
                    UpdateTime = DateTime.Now
                };
                OperateContext.CurrentContext.BllSession.IRateOfExchange_BLL.ModifyIsNullADD(rate, s => s.CurrencyID == item.Key && s.RateType == RateType && s.IsDel == false, false, "Rate", "UpdateUser", "UpdateTime");
            }
            return OperateContext.CurrentContext.BllSession.SaveChanges(typeof(RateOfExchange).Name);
        }
        #endregion

        #region 1.6 汇率分析（2，4，6，14，30） +static int AnalysisExchangeRate(string version, List<int> CurrencyIDList)
        /// <summary>
        /// 1.6 汇率分析（2，4，6，14，30）
        /// </summary>
        /// <param name="version"></param>
        /// <param name="CurrencyIDList"></param>
        /// <returns></returns>
        public static int AnalysisExchangeRate(string version, List<int> CurrencyIDList)
        {
            DateTime
                day30 = DateTime.Now.AddDays(-30),
                day2 = DateTime.Now.AddDays(-2),
                day4 = DateTime.Now.AddDays(-4),
                day6 = DateTime.Now.AddDays(-6),
                day14 = DateTime.Now.AddDays(-14);
            //DateTime[] day = { day30, day2, day4, day6, day14 };
            List<RateOfExchangeHistory> list = OperateContext.CurrentContext.BllSession.IRateOfExchangeHistory_BLL.GetListByWhere(s => s.IsDel == false && s.CreateTime >= day30);
            if (list.Count < 1) return -1;
            foreach (var CurrencyID in CurrencyIDList)
            {
                if (CurrencyID == 0) continue;

                RateOfExchangeAnalysi model = new RateOfExchangeAnalysi();
                model.Rate2 = Math.Round(list.Where(s => (s.UpdateTime >= day2 || s.CreateTime >= day2) && s.CurrencyID == CurrencyID).Average(s => s.Rate), 3);
                model.Rate4 = Math.Round(list.Where(s => (s.UpdateTime >= day4 || s.CreateTime >= day4) && s.CurrencyID == CurrencyID).Average(s => s.Rate), 3);
                model.Rate6 = Math.Round(list.Where(s => (s.UpdateTime >= day6 || s.CreateTime >= day6) && s.CurrencyID == CurrencyID).Average(s => s.Rate), 3);
                model.Rate14 = Math.Round(list.Where(s => (s.UpdateTime > day14 || s.CreateTime > day14) && s.CurrencyID == CurrencyID).Average(s => s.Rate), 3);
                model.Rate30 = Math.Round(list.Where(s => s.CurrencyID == CurrencyID).Average(s => s.Rate), 3);
                model.IsDel = false;
                model.CurrencyID = CurrencyID;
                model.AnalysisVersion = version;
                model.CreateUser = "Analysis";
                model.CreateTime = DateTime.Now;
                model.UpdateUser = "RateAnaly";
                model.UpdateTime = DateTime.Now;
                OperateContext.CurrentContext.BllSession.IRateOfExchangeAnalysi_BLL.ADD(model);
            }
            return OperateContext.CurrentContext.BllSession.SaveChanges(typeof(RateOfExchangeAnalysi).Name);
        }
        #endregion

        #region 1.7 汇率波动 + static List<RateFluctuationModel> RateFluctuation(List<RateOfExchange> Rate1, List<RateOfExchange> Rate0, Dictionary<int, decimal> Rate)
        /// <summary>
        /// 汇率波动
        /// </summary>
        /// <param name="Rate1">定价汇率</param>
        /// <param name="Rate0">结算汇率</param>
        /// <param name="Rate">时实汇率</param>        
        /// <returns>汇率波动信息</returns>
        public static List<RateFluctuationModel> RateFluctuation(List<RateOfExchange> Rate1, List<RateOfExchange> Rate0, Dictionary<int, decimal> Rate)
        {
            List<RateFluctuationModel> list = new List<RateFluctuationModel>();
            foreach (var item in Rate)
            {
                RateOfExchange rateOfExchange0 = Rate0.Where(s => s.CurrencyID == item.Key && s.IsDel == false && s.RateType == false).FirstOrDefault();
                RateOfExchange rateOfExchange1 = Rate1.Where(s => s.CurrencyID == item.Key && s.IsDel == false && s.RateType == true).FirstOrDefault();

                decimal r0 = rateOfExchange0.Rate, r1 = rateOfExchange1.Rate;

                decimal r = Rate.Where(s => s.Key == item.Key).FirstOrDefault().Value;

                list.Add(new RateFluctuationModel()
                {
                    CurrencyID = rateOfExchange0.CurrencyID,
                    Rate0 = r0,
                    Rate1 = r1,
                    Rate = r,
                    Fluctuation0 = Math.Round((r0 - r) / r, 2),
                    Fluctuation1 = Math.Round((r1 - r) / r, 2)
                });
            }
            return list;
        }
        #endregion


        public static int UpdateRate(List<int> listCurrencyId, string version)
        {
            List<RateOfExchangeAnalysi> list = OperateContext.CurrentContext.BllSession.IRateOfExchangeAnalysi_BLL.GetListByWhere(s => s.AnalysisVersion == version && listCurrencyId.Contains(s.CurrencyID));
            if (list.Count < 1) return -1;
            RateOfExchange rate = null;
            foreach (var item in list)
            {
                rate = new RateOfExchange()
                {
                    Rate = Math.Round(((item.Rate6 + item.Rate4 + item.Rate2) ?? -9999) / 3, 3),
                    CreateTime = DateTime.Now,
                    CreateUser = "RateFluctuation",
                    UpdateTime = DateTime.Now,
                    UpdateUser = "波动",
                    RateType = true,
                    CurrencyID = item.CurrencyID,
                    IsDel = false
                };
                if (rate.Rate == -3333)
                {
                    rate.UpdateUser = "分析值为NULL";
                    OperateContext.CurrentContext.BllSession.IRateOfExchange_BLL.Modify(rate, s => s.IsDel == rate.IsDel && s.CurrencyID == rate.CurrencyID && s.RateType == rate.RateType, "CreateTime", "CreateUser", "UpdateTime", "UpdateUser");
                }
                else
                {
                    OperateContext.CurrentContext.BllSession.IRateOfExchange_BLL.Modify(rate, s => s.IsDel == rate.IsDel && s.CurrencyID == rate.CurrencyID && s.RateType == rate.RateType, "Rate", "CreateTime", "CreateUser", "UpdateTime", "UpdateUser");
                }
            }
            return OperateContext.CurrentContext.BllSession.SaveChanges(typeof(RateOfExchange).Name);
        }
    }
}
